package com.lemon.springcloud.core;

import com.lemon.springcloud.core.initial.DefaultLemonApplicationInitializer;
import com.lemon.springcloud.core.initial.LemonApplicationInitializer;
import com.lemon.springcloud.core.spring.factory.CoreBeanPostProcessor;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;
import java.util.List;
import java.util.Map;

/**
 * @author hdzhang
 * @ClassName EnableLemonAutoConfigurationImport
 * @desc
 * @Date 2018/9/7 18:54
 * @Version 1.0
 **/
public class EnableLemonAutoConfigurationImport implements DeferredImportSelector, BeanClassLoaderAware {

    private ClassLoader classLoader;

    public EnableLemonAutoConfigurationImport() {

    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        LemonApplicationInitializer.setLemonApplicationInitializerEnable(true);
        this.classLoader = classLoader;
    }

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        List<String> beansToInjectList = SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, this.classLoader);
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableLemonAutoConfiguration.class.getName());

        // 加载自定义组件
        this.loadSupportedComponents(beansToInjectList, annotationAttributes);

        // 加载 LemonApplicationInitializer
        beansToInjectList.add(DefaultLemonApplicationInitializer.class.getName());

        return beansToInjectList.toArray(new String[0]);
    }

    /**
     * 加载启用的组件
     * @param beanNames
     * @param annotationAttributes
     */
    private void loadSupportedComponents(List<String> beanNames, Map<String, Object> annotationAttributes) {
        Boolean mybatis = (Boolean) annotationAttributes.get("mybatis");
        Boolean redis = (Boolean) annotationAttributes.get("redis");
        Boolean rabbitmq = (Boolean) annotationAttributes.get("rabbitmq");
        Boolean zookeeper = (Boolean) annotationAttributes.get("zookeeper");
        Boolean es = (Boolean) annotationAttributes.get("es");

        if (mybatis) {
            LemonApplicationInitializer.setLemonBuildMybatisEnable(true);
            addApplicationInitializer(beanNames);
        }

        if (redis) {
            LemonApplicationInitializer.setLemonBuildRedisEnable(true);
            addApplicationInitializer(beanNames);
        }

        if (rabbitmq) {
            LemonApplicationInitializer.setLemonBuildRabbitMQEnable(true);
            addApplicationInitializer(beanNames);
        }

        if (zookeeper) {
            LemonApplicationInitializer.setLemonBuildInZkEnable(true);
            addApplicationInitializer(beanNames);
        }

        if (es) {
            LemonApplicationInitializer.setLemonBuildInEsEnable(true);
            addApplicationInitializer(beanNames);
        }
    }

    private void addApplicationInitializer(List<String> beanNames) {
        if (!beanNames.contains(CoreBeanPostProcessor.class.getName())) {
            beanNames.add(CoreBeanPostProcessor.class.getName());
        }
    }
}
